import { AudioClip, AudioSource, Component, _decorator } from 'cc';
import { SoundCode } from '../Config/BaseEnum';
import { LoadingManager } from './LoadingManager';
import { GameData } from './DataManager';
import { GameParams } from '../Config/DataConfig';
import { GameModel } from '../../Game/Game/GameModel';

const { ccclass, property } = _decorator;

@ccclass('AudioManager')
export class AudioManager extends Component {
  static Singleton: AudioManager;

  @property(AudioSource)
  bgmAudioSource: AudioSource;

  private _tempBgm: Set<AudioClip> = new Set();
  readyPlay: boolean = false;
  constructor() {
    super();
    AudioManager.Singleton = this;
  }

  checkBgm() {
    console.log('checkBgm', this.readyPlay);
    if (this.readyPlay) {
      this.readyPlay = false;
      if (this.bgmAudioSource.clip != null) {
        this.bgmAudioSource.stop();
        this.bgmAudioSource.play();
      } else {
        this.loadAndPlayMusic(GameModel.Ins().basePanel != null && GameModel.Ins().basePanel.parent != null ? SoundCode.BGM_GAME : SoundCode.BGM_MAIN);
      }
    }
  }

  async loadAndPlayMusic(code: SoundCode, isLoop: boolean = true, volume: number = 1) {
    if (!GameData.get(GameParams.gameMusic)) {
      if (this.bgmAudioSource.clip) this.bgmAudioSource.stop();
      this.bgmAudioSource.clip = null;
      return;
    }

    const music = await LoadingManager.Ins().getLoadRes<AudioClip>(code);
    if (music !== this.bgmAudioSource.clip && !this._tempBgm.has(music)) {
      music.addRef();
    }
    this.playBgmMusic(music, isLoop, volume);
  }

  playBgmMusic(music: AudioClip, isLoop: boolean = true, volume: number = 1) {
    if (this.bgmAudioSource.clip === music) return;

    this.bgmAudioSource.stop();

    if (this.bgmAudioSource.clip) {
      this._tempBgm.add(this.bgmAudioSource.clip);
    }

    if (this._tempBgm.has(music)) {
      this._tempBgm.delete(music);
    }

    this.bgmAudioSource.clip = music;
    this.bgmAudioSource.volume = volume;
    this.bgmAudioSource.loop = isLoop;
    this.bgmAudioSource.play();

    if (this._tempBgm.size > 2) {
      const clip = this._tempBgm.values().next().value;
      this._tempBgm.delete(clip);
      clip.decRef();
    }
  }

  /** 播放音效 */
  async playSound(code: SoundCode, volume: number = 1) {
    if (!GameData.get(GameParams.gameSound)) return;
    const sound = await LoadingManager.Ins().getLoadRes<AudioClip>(code);
    this.bgmAudioSource.playOneShot(sound, volume);
  }
}
